package managedbean.tourist;

import entity.CuisinePrefEntity;
import entity.InterestPrefEntity;
import util.enumeration.Country;
import exception.ExistException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import session.stateless.SystemMessagesBean;
import session.stateless.TouristAccountSessionBean;
import util.entityhelper.TouristAccountState;
import util.enumeration.CuisineType;
import util.enumeration.Gender;
import util.enumeration.Interest;
import util.localization.WebLocalization;

/**
 *
 * @author Swee Zhi
 */
@ManagedBean
@RequestScoped
public class TouristRegisterManagedBean implements Serializable {
    @EJB
    private TouristAccountSessionBean touristAccountMgr;
    // display exception
    @EJB
    private SystemMessagesBean systemMessages;
    
    private FacesContext ctx = FacesContext.getCurrentInstance();
    private WebLocalization localization;
    
    // use entity helpers to extract data (attribute extraction and formatting instead of entity in this open bean)
    private TouristAccountState touristAcctState;
    
    //  user preferred locale
    private String preferredLocale;
    
    // other fields from database
    private String username;
    private String password;
    private String confirmPassword;
    private String lastname;
    private String firstname;
    private String gender;
    private Date birthdate;
    private String country;
    private String locale;
    private String email;
    private String emailSecondary;
    private List<CuisineType> cuisineTypeList;
    private List<Interest> interestList;
    
    private String statusPasswordLength;
    private String statusPasswordMatch;

    public TouristRegisterManagedBean() {
        /* LOCALIZATION */
        localization = new WebLocalization();
        preferredLocale = localization.getPreferredLocaleFromSession();
        /* END LOCALIZATION */
    }
    
    public void registerTourist(ActionEvent event) {    
        // set language for all MANAGERS for all THROWABLE display exceptions in backend
        // to use this line everytime language changes
        touristAccountMgr.setSelectedLocale(preferredLocale);
            
        try {
            if (checkUsernameAvailability(username) == true) {
                // set language for all MANAGERS for all THROWABLE display exceptions in backend
                // to use this line everytime language changes
                touristAccountMgr.setSelectedLocale(preferredLocale);

                Gender g = Gender.valueOf(gender);
                Country c = Country.valueOf(country);
                // email = username
                
                List<CuisinePrefEntity> newCuisinePrefList = new ArrayList<CuisinePrefEntity>();
                for (CuisineType ct : cuisineTypeList) {
                    CuisinePrefEntity newCuisinePref = new CuisinePrefEntity();
                    newCuisinePref.setCuisineType(ct);
                    newCuisinePrefList.add(newCuisinePref);
                }

                List<InterestPrefEntity> newInterestPrefList = new ArrayList<InterestPrefEntity>();
                for (Interest i : interestList) {
                    InterestPrefEntity newInterestPref = new InterestPrefEntity();
                    newInterestPref.setInterest(i);
                    newInterestPrefList.add(newInterestPref);
                }
                
                touristAccountMgr.createTouristAccount(username, password, lastname, firstname, g, birthdate, c, locale, username, emailSecondary, newCuisinePrefList, newInterestPrefList);
                

                // print success message
                String statusMessage = systemMessages.getSystemMessage("ACCOUNT_CREATION_SUCCESS", preferredLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, ""));

                reset();
            }
        }
        catch (ExistException ex) {
            // display exception
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
            System.out.println("caught 2");
        }
        catch (Exception ex) {
            // display exception tp user
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
            // backend message for Tcube
            ex.printStackTrace();   
        }
    }
        
    private void reset() {
        username = "";
        password = "";
        confirmPassword = "";
        lastname = "";
        firstname = "";
        gender = "";
        birthdate = null;
        country = "";
        locale = "";
        email = "";
        emailSecondary = "";
        cuisineTypeList.clear();
        interestList.clear();
    }
    
    public boolean validateEmailFormat(String emailInput) {
        Pattern p = Pattern.compile(".+@.+\\.[a-z]+");
        Matcher m = p.matcher(emailInput);
        boolean matchFound = m.matches();

        if (!matchFound) {
            // means error
            return false;
        }
        return true;
    }
    
//    public void checkUsernameAvailability(ActionEvent event) {
    public boolean checkUsernameAvailability(String username) {
        touristAccountMgr.setSelectedLocale(preferredLocale);

        try {
            touristAcctState = touristAccountMgr.getTouristAccountByUsername(username);
        }
        catch (ExistException ex) {
            // if nothing is found, good
            System.out.println("caught 1");
            return true;
        }
        
        // print error message
        String statusMessage = systemMessages.getSystemMessage("USERNAME_NOT_OK", preferredLocale);
        FacesContext.getCurrentInstance().addMessage(username, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
        
        return false;
    }

    public TouristAccountSessionBean getTouristAccountMgr() {
        return touristAccountMgr;
    }

    public void setTouristAccountMgr(TouristAccountSessionBean touristAccountMgr) {
        this.touristAccountMgr = touristAccountMgr;
    }

    public Date getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(Date birthdate) {
        this.birthdate = birthdate;
    }

    public FacesContext getCtx() {
        return ctx;
    }

    public void setCtx(FacesContext ctx) {
        this.ctx = ctx;
    }
    
    public String getConfirmPassword() {
        return confirmPassword;
    }

    public void setConfirmPassword(String confirmPassword) {
        this.confirmPassword = confirmPassword;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getStatusPasswordLength() {
        return statusPasswordLength;
    }

    public void setStatusPasswordLength(String statusPasswordLength) {
        this.statusPasswordLength = statusPasswordLength;
    }

    public String getStatusPasswordMatch() {
        return statusPasswordMatch;
    }

    public void setStatusPasswordMatch(String statusPasswordMatch) {
        this.statusPasswordMatch = statusPasswordMatch;
    }

    public SystemMessagesBean getSystemMessages() {
        return systemMessages;
    }

    public void setSystemMessages(SystemMessagesBean systemMessages) {
        this.systemMessages = systemMessages;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getLocale() {
        return locale;
    }

    public void setLocale(String locale) {
        this.locale = locale;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmailSecondary() {
        return emailSecondary;
    }

    public void setEmailSecondary(String emailSecondary) {
        this.emailSecondary = emailSecondary;
    }

    public String getPreferredLocale() {
        return preferredLocale;
    }

    public void setPreferredLocale(String preferredLocale) {
        this.preferredLocale = preferredLocale;
    }

    public WebLocalization getLocalization() {
        return localization;
    }

    public void setLocalization(WebLocalization localization) {
        this.localization = localization;
    }

    public List<CuisineType> getCuisineTypeList() {
        return cuisineTypeList;
    }

    public void setCuisineTypeList(List<CuisineType> cuisineTypeList) {
        this.cuisineTypeList = cuisineTypeList;
    }

    public List<Interest> getInterestList() {
        return interestList;
    }

    public void setInterestList(List<Interest> interestList) {
        this.interestList = interestList;
    }

    public TouristAccountState getTouristAcctState() {
        return touristAcctState;
    }

    public void setTouristAcctState(TouristAccountState touristAcctState) {
        this.touristAcctState = touristAcctState;
    }
}
